<?php
abstract class Unit{
    function getComposite(){
        return null;
    }
    function textDump($num = 0){
        $ret = '';
        $pad = 4*$num;
        $ret .= sprintf("%{$pad}s","");
        $ret .= get_class($this).":";
        $ret .= "bombard:".$this->bombardStrength();
        return $ret;
    }

    function accept(ArmyVisitor $visitor){
        $method = "Vist".get_class($visitor);
        $visitor->$method($this);
    }
    protected function setDepth($depth){
        $this->depth = $depth;
    }

    function getDepth(){
        return $this->depth;
    }

    abstract function bombardStrength();
}

abstract class CompositeUnit extends Unit{
    private $units = array();
    function getComposite(){
        return $this;
    }
    protected function getUnits(){
        return $this->units;
    }
    public function addUnit(Unit $unit){
        foreach($this->units as $thisunit){
            if($unit === $thisunit){
                return ;
            }
        }
        array_push($this->units,$unit);
    }

    public function removeUnit(Unit $unit){
        $this->units = array_udiff($this->units,array($unit),function($a,$b){
            return ($a === $b)?0:1;
        });
    }

    function textDump($num = 0){
        $ret = parent::textDump();
        foreach($this->units as $unit){
           $ret .= $unit->textDump($num +1);
        }
        return $ret;
    }

    function accept(ArmyVisitor $visitor){
        parent::accept($visitor);
        foreach($this->units as $thisunit){
            $thisunit->accept($visitor);
        }
    }

}

class Archer extends Unit{

    public function addUnit(Unit $unit){
        throw new Exception('不能用啊');
    }

    public function removeUnit(Unit $unit){
        throw new Exception('不能用啊');
    }

    public function bombardStrength()
    {
        return 4;
    }
}

//激光兵
class LaserCannonUnit extends Unit{

    public function addUnit(Unit $unit){
        throw new Exception('不能用啊');
    }

    public function removeUnit(Unit $unit){
        throw new Exception('不能用啊');
    }
    public function bombardStrength()
    {
        return 44;
    }
}

class Army extends CompositeUnit{
    private $units = array();

    public function addUnit(Unit $unit){
        array_push($this->units,$unit);
    }

    public function removeUnit(Unit $unit){
        $this->units = array_udiff($this->units,array($unit),function($a,$b){
            return ($a === $b)?0:1;
        });
    }
    public function bombardStrength(){
        $ret = 0;
        foreach($this->units as $unit){
            $ret += $unit->bombardStrength();
        }
        return $ret;
    }
}

$pad = 4;

echo sprintf("%{$pad}s",'');